package com.pqy.ts.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pqy.ts.entity.TComment;
import com.pqy.ts.entity.vo.CommentVo;
import com.pqy.ts.mapper.TCommentMapper;
import com.pqy.ts.service.TCommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  评论服务实现类
 * </p>
 *
 * @author panqiyi
 * @since 2022-06-05
 */
@Service
public class TCommentVOServiceImpl extends ServiceImpl<TCommentMapper, TComment> implements TCommentService {


    // 保存评论
    @Override
    public Boolean saveComment(TComment TComment) {
        boolean save = save(TComment);
        return save;
    }

    // 返回 评论列表
    @Override
    public List<CommentVo> getCommentList(String itemId) {
        // 1、获取id=itemId文章下的 所有评论
        QueryWrapper<TComment> allwrapper = new QueryWrapper<>();
        allwrapper.eq("item_id",itemId);
        List<TComment> allList = list(allwrapper); // 所有评论集合

        // 遍历所有评论集合，复制到 评论视图返回类
        ArrayList<CommentVo> commentVos = new ArrayList<>(); //评论视图返回类 集合
        for (TComment tComment : allList) {
            CommentVo commentVo = new CommentVo();
            BeanUtils.copyProperties(tComment,commentVo);
            commentVo.setTime(tComment.getTCreate()); // 时间
            commentVo.setComment(tComment.getContent()); // 内容
            commentVos.add(commentVo);
        }

//        for (CommentVo commentVo : commentVos) {
//            System.out.println(commentVo);
//        }
//
//        System.out.println("..................");

        ArrayList<CommentVo> com = new ArrayList<>(); // 最终集合
        HashMap<String, CommentVo> map = new HashMap<>();

        // 2、com集合存储顶级评论
        for (CommentVo tComment : commentVos) { // 遍历每一条评论
            if ("0".equals(tComment.getParentId())){
                // 顶级评论
                com.add(tComment);
            }
            map.put(tComment.getId(),tComment); // 所有评论  id:评论对象
        }

       //  3、com集合内顶级评论 存储所有包含的子级评论
        for (CommentVo tComment : commentVos) { // 遍历每一条评论
            if (!"0".equals(tComment.getParentId())){ // 非顶级评论，既第一子级、第二子级等等评论
                // 获取所有父级评论 (如 a->b, b->c, c->d, d="0")
                CommentVo parent = map.get(tComment.getParentId());

                if (parent == null){
                    continue; // 跳出本次循环
                }

                if (parent.getId().equals(tComment.getId())){
                    continue;
                }
                parent.getReply().add(tComment); // 所有父级存储子级 （b(reply[b]), c(replay[b(reply[a])]) ....）

            }
        }

        /*System.out.println("=================");
        for (CommentVo tComment : com) {
            System.out.println(tComment);
        }*/

        // 结果是 顶级包含子级，子级包含孙级....，层次嵌套，
        // 但是我们想返回的是 父级>子级（包含所有子子孙孙） 两层
        // 组装好的评论数据
        List<CommentVo> formatList = getFormat(com);

        return formatList;
    }



    // 存储 新组装好的 子级（子子孙孙） 数据集合
    ArrayList<CommentVo> newReplys = new ArrayList<>();
    /**
     * 重新组装评论集合，使其只有两层 顶级评论>第一子级评论（包含子级和子子孙孙）
     * @param com
     * @return
     */
    public List<CommentVo> getFormat(List<CommentVo> com){

        for (CommentVo tComment : com) { // 遍历顶点集合
            // 获取顶点 子级集合
            List<CommentVo> replys = tComment.getReply();
            for (CommentVo comment : replys) { // 遍历第一级（子级）回复集合  ( for(:) 只有集合元素>0才会进入)
                newReplys.add(comment); // 存储第一级子评论
                recursively(comment); // 递归子级评论
            }
            tComment.setReply(newReplys); // 重新设置子级（包含子子孙孙）
            tComment.setCommentNum(newReplys.size()); // 低级评论回复数
            // 新建（或清除）组装集合，避免下一轮顶点集合组装有数据
            newReplys = new ArrayList<>();
        }
        return com;
    }

   /**
     * 递归子级评论，返回顶级评论下 所有子代 都放到第一子级评论中
     * @param comment
     */
    private void recursively(CommentVo comment){
        List<CommentVo> replys = comment.getReply(); // 第二子级集合
        if (replys.size()>0){ // 存在评论
            for (CommentVo reply : replys) {
                newReplys.add(reply); // 存储
                if (reply.getReply().size()>0){
                    recursively(reply); // 递归
                }
            }
        }
    }

}
